/**
* file name  : GetCSV.java
* authors    : Luciano Xumerle
* created    : ven 12 ago 2005 15:49:47 CEST
*
* Copyright (c) 2004-2005 Luciano Xumerle. All rights reserved.
*
* This file is part of gephinfo.
*
* gephinfo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*/

package it.ciano.jenoware;

import java.util.HashSet;
import java.util.ArrayList;
import it.ciano.util.CFile;
import it.ciano.util.CString;

/**
 * The class GetARFF provides an interface to export data contained Pedigree
 * into a Pedigree object to an ARFF file.
 *
 * @author Luciano Xumerle
 * @version 0.0.1
 */
public class GetARFF extends GetFile {

    //
    // private vars used to store the field names
    //
    private Sbj ids[];
    private String pheno[];
    private String geno[];

    // use string attributes?
    boolean useString;

    private HashSet _nullPhenotype;

    final private static String ext=".arff";

    /**
     * Class Constructor.
     *
     * @param pedigree a populated Pedigree object.
     * @param useStringAttributes if true the program uses the string attributes.
     */
    public GetARFF ( Pedigree pedigree, boolean useStringAttributes ) {
        super ( pedigree );
        ids = pedigree.getUnrelatedSbj();
        pheno = getPed().getPhenotypesList();
        geno = getPed().getMarkersList();
        useString=useStringAttributes;
        _nullPhenotype=new HashSet();
    }

    /**
     * Class Constructor.
     * The program uses the string attributes.
     *
     * @param pedigree a populated Pedigree object.
     */
    public GetARFF ( Pedigree pedigree ) {
        this ( pedigree, true     );
    }

    /**
     * Overriding toString method
     *
     * @return all informations that will be contained into the destination files.
     */
    public String toString() {
        StringBuffer res = new StringBuffer();
        res.append ( "% ARRF file generated by Jenoware\n" );
        res.append ( "@RELATION pedigree\n\n" );

        /**
         * ADD SBJ INFORMATIONS
         */
        if ( useString )
            res.append ( "@ATTRIBUTE id string\n" );
        res.append ( "@ATTRIBUTE sex        {1,2}\n" );

        /**
         * ADD PHENOTYPE
         */
        for ( int i=0; i<pheno.length; i++ ) {
            PhenotypeFreq t= new  PhenotypeFreq ( getPed(), pheno[i] );
            if ( t.isAffected() ) {
                res.append ( "@ATTRIBUTE " +  pheno[i] + " {"
                             + CString.join ( t.getObservedPhenotypes() ,  "," ) + "}\n" );
            } else if ( t.isTrait()  ) {
                res.append ( "@ATTRIBUTE "+pheno[i]  + " NUMERIC\n" );
            } else {
                _nullPhenotype.add ( pheno[i] );
                if ( useString )                res.append ( "@ATTRIBUTE "+pheno[i]  + " string\n" );
            }
        }

        /**
         * ADD GENOTYPES
         */
        for ( int i=0; i<geno.length; i++ ) {
            MarkerFreq t=new MarkerFreq ( getPed(), geno[i] );
            Genotype[] l= t.getOrderedGenotypeList();
            String s[]=new String[ l.length ];
            for ( int j=0; j<l.length; j++ )
                s[j]=l[j].getConcatAlleles();
            res.append ( "@ATTRIBUTE " +  geno[i] + " {"
                         + CString.join ( s,  "," ) + "}\n" );
        }

        /**
         * ADD DATA
         */
        res.append ( "@DATA\n" );
        for ( int i=0; i<ids.length; i++ ) {
            ArrayList t=new ArrayList();
            // id is a string attributes
            if ( useString )            t.add (   ids[i].getID() );
            String sex=ids[i].getSEX();
            if ( sex.equals ( "" ) )
                t.add (  "?" );
            else
                t.add (  ids[i].getSEX() );

            for ( int j=0; j<pheno.length; j++ )
                if ( !_nullPhenotype.contains ( pheno[j] )  ) {
                    if (  ids[i].getPhenotype (  pheno[j]  ).getValue().equals ( "" )     )
                        t.add ( "?" );
                    else
                        t.add (   ids[i].getPhenotype (  pheno[j]  ).getValue()  );
                }

            for ( int j=0; j<geno.length; j++ )
                if ( ids[i].getGenotype (  geno[j]  ).isValid() )
                    t.add (   ids[i].getGenotype (  geno[j]  ).getConcatAlleles()  );
                else
                    t.add ( "?" );

            String[] s=new String[ t.size() ];
            for ( int j=0; j<t.size(); j++ ) {
                s[j]= ( String ) t.get ( j );
            }
            res.append ( CString.join ( s,  "," )   +"\n" );
        }

        return res.toString();
    }

    /**
     * Creates a CSV file with the given name.
     *
     * @return true if all operations are ok.
     */
    public boolean createsFile ( String filename ) {
        setFilename ( filename );
        return CFile.saveString ( getFilename() + ext, toString() );
    }

    /**
     * Creates a CSV file named "out.arff".
     *
     * @return true if all operations are ok.
     */
    public boolean createsFile() {
        return CFile.saveString ( getFilename() + ext, toString() );
    }


} // end class

